package com.zxt.web.handler;

import com.zxt.bean.Result;
import com.zxt.bean.ResultCode;
import com.zxt.bean.ServiceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.Arrays;
import java.util.Objects;

@ResponseBody
@RestControllerAdvice
public class GlobalExceptionHandler {
    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    public GlobalExceptionHandler() {
    }

    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    public Result<String> handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
        String[] supportedMethods = e.getSupportedMethods();
        return Objects.isNull(supportedMethods) ? Result.newError(ResultCode.C405) : Result.newError(ResultCode.C405, new Object[]{Arrays.toString(supportedMethods)});
    }

    @ExceptionHandler({HttpMessageNotReadableException.class})
    public Result<String> handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
        log.warn("参数异常", e);
        return Result.newError("参数异常");
    }

    @ExceptionHandler({Throwable.class, MethodArgumentNotValidException.class})
    public Result<String> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.warn("参数异常", e);
        String defaultMessage = ((FieldError) e.getBindingResult().getFieldErrors().get(0)).getDefaultMessage();
        return Result.newError(defaultMessage);
    }

    @ExceptionHandler({MissingServletRequestParameterException.class})
    public Result<String> handleMissingServletRequestParameterException(MissingServletRequestParameterException e) {
        log.warn("参数异常", e);
        return Result.newError(e.getMessage());
    }

    @ExceptionHandler({HttpMediaTypeNotSupportedException.class})
    public Result<String> handleHttpMediaTypeNotSupportedException(HttpMediaTypeNotSupportedException e) {
        log.warn("参数异常", e);
        return Result.newError(e.getMessage());
    }

    @ExceptionHandler({ServiceException.class})
    public Result<String> handleServiceException(ServiceException e) {
        log.warn("业务异常: {}", e.getMessage(), e);
        Result<String> result = Result.newSuccess();
        result.setSuccess(false);
        result.setCode(e.getCode());
        result.setMessage(e.getMessage());
        return result;
    }

    @ExceptionHandler({Exception.class})
    public Result<String> handleException(Exception e) {
        log.error("Occur exception!", e);
        return Result.newError(ResultCode.SYS_ERROR);
    }
}

